import http from "http"

// 获取配置并且解析配置
import ConfigHandler from './init/ConfigHandler'
/** 处理配置文件 */
import Config from './init/ConfigControl'
/** 经过上面的初始化后可以 初始化一些配置  */ 
import './init/main'
/** 主入口 */
import inlet from './entrance/inlet'
/** 路由解析 */
import run_route from './route/RouterPars'
/** 注解扫描器 */
import auto_load_interface from './auto_load/auto_load'
/** 热部署 */
import monitor from './monitor/Monitor'
/** 路由 */
import Route from './route/Router'
/** 时间工具 */
import tools from './utils/DateUtils'
/** 输出颜色 */
import color from './utils/Color';
/** 路径语法糖 */
import sugar from './core/sugar';
/** 跨域 */
import cross from "./plug-in/crossDomain";
// 自动加载路由
import auto_load_route from "./annotation/auto_load_route"
// 捕捉未被处理的全局异常
import { middleware } from './gem';
import Middleware from './middleware/middleware'
const startRun:Array<Function> = [];
const endRun:Array<Function> = [()=>{
    // 更新下本地ip
    cross.update_local_ip();
}];
// 加载一下路由，这样用户可以直接用.get.post

export = class index{
    public createCgem(){ return new index() }
    public createRoute (){return new Route(sugar.super_path(2,true))}

    /** 框架的配置信息 也就是vue.config.json中的内容 */
    public config = Config;
    /** 自动加载路由 */
    public auto_load = auto_load_route;
    /** 跨域组件 */
    public static cross: any = cross;
    // 不再对路由中的方法进行转发， 直接创建路由实例
    public route = new Route({id:__filename});

    //启动框架服务
    public async start(config:any,host?:string,callback?:Function,add?:boolean){
        for(let e of startRun){await e()}
        if(typeof config === "object"){
            config.host && (ConfigHandler.setServers("host",config.host))
            config.port && (ConfigHandler.setServers("port",Number(config.port)))
            ConfigHandler.setServers("callback",host)
            ConfigHandler.setServers("add",callback);
        }else if(typeof config === "function"){
            // 只有回调
            ConfigHandler.setServers("callback",config);
            ConfigHandler.setServers("add",host);
        }else if(host){
            ConfigHandler.setServers("host",host)
            ConfigHandler.setServers("port",Number(config))
            ConfigHandler.setServers("callback",callback)
            ConfigHandler.setServers("add",add);
        }
        //初始化一些数据
        this.init().then(_=> {
            ConfigHandler.setServers("port",Number(ConfigHandler.getServers("port")));
            // ===================================================启动服务,并且加载入口文件
            const server = http.createServer(inlet);
            server.listen(ConfigHandler.getServers("port") as number, ConfigHandler.getServers("host") as string,()=>ts(ConfigHandler.getServers("callback") as Function));
            server.on("error", () => {
                console.log(`${color("灰色",ConfigHandler.getServers("port"))} 端口被占用,改端口为 ${color("绿色",ConfigHandler.getServers("port") as number + 1)}`)
                ConfigHandler.setServers("port",ConfigHandler.getServers("port") as number + 1);
                server.listen(ConfigHandler.getServers("port"));
            });
        }).catch(err=>{
            console.log(err)
        });
    }


    // 添加项目需要使用到的扩展
    public use(plug:middleware):void{
        //加载的组件 进全局中间件
        ConfigHandler.addPlug((plug as any)?.default || plug)
    }
    // 添加全局中间件
    public useGlobal(data:any):void{this.config.addGlobalMiddleware(data)}

    public start_run(fun:Function){startRun.push(fun)}
    public end_run(fun:Function){endRun.push(fun)}

    //初始化模块 以及环境
    public async init(){
        // 配置初始化
        ConfigHandler.init(Middleware);   

        // 运行注解 必须先运行注解，不然靠注解生成的注解模块就会无法使用
        ConfigHandler.getAddress("middleware") &&
        ConfigHandler.addrunAnnotation(ConfigHandler.getAddress("middleware"));
        ConfigHandler.getAddress("controller") &&
        ConfigHandler.addrunAnnotation(ConfigHandler.getAddress("controller"));
        
        // 运行注解
        await auto_load_interface(ConfigHandler.getrunAnnotation());

        // 解析路由
        await run_route.init();

        // 启动热部署
        await monitor({
            // 控制器热部署
            Controller:ConfigHandler.getAddress("controller"),
            // 路由文件热部署
            route_arr: ConfigHandler.getRouteConfig().map(e=>e.path),
            // 监控注解
            annotation:ConfigHandler.getrunAnnotation()
        },ConfigHandler.getFeatures("hotDeployment"));
    }


    // 创建cgem的实例
    public static createCgem(){
      return new index();
    }
    /** 创建路由 */
    public static createRoute (){return new Route(sugar.super_path(2,true))}

}

//提示
async function ts(callback?:Function){
    if(global.web_status === undefined){
        for(let f of endRun){await f()}
        // 置顶一下
        global.web_status=true;
        loader("./init/banner")

        let IP:any = tools.local_ip();
        if(ConfigHandler.getServers("add") || !callback){
            console.log(color("青色","\nCGEM框架运行成功,请使用以下网址访问网站"));
            if(ConfigHandler.getServers("host") === "0.0.0.0"){
                Object.keys(IP).forEach(ip=>{
                    console.log(color("绿色",`Server running at `+color("蓝色",`http://${IP[ip].address+":"+ConfigHandler.getServers("port")}/`)));
                })
            }else{
                console.log(color("绿色",`Server running at http://${ConfigHandler.getServers("host")}:${ConfigHandler.getServers("port")}/`));
            }
        }
        callback && callback(IP,ConfigHandler.getServers("port"))
        console.log();
    }
}

// set-ExecutionPolicy RemoteSigned
/**
git config --global user.email "2844087515@qq.com"
git config --global user.name "baige" 
 */